home *** CD-ROM | disk | FTP | other *** search
- { TransSkel multiple-window demonstration: ZoomRect module}
-
- { This module handles a window in which successive randomly generated}
- { rectangles are smoothly interpolated into one another. The display}
- { is white on black, which results in some interesting problems (see}
- { ZDrawGrowBox, for instance). The display adjusts itself to the size}
- { of the window, so that the zoom series always lie entirely within}
- { the window. Clicking the mouse in the window pauses the display until}
- { the button is released.}
-
- { 14 June 1986 Paul DuBois}
- { 7 January 1987 ported to LightSpeed Pascal by Owen Hartnett }
- { Ωhm Software Company. }
-
-
- UNIT MSkelZoom;
-
- INTERFACE
-
- USES
- MultiSkelGlobs, common, TransSkelpas;
-
- PROCEDURE ZoomWindInit;
-
- IMPLEMENTATION
-
-
- CONST
- zoomSteps = 15; { # rects in interpolative series }
-
- VAR
- zRect : ARRAY[0..zoomSteps] OF Rect; { set of interpolated rectangles }
- zSrcRect : Rect;
- sizeX, sizeY : integer; { size of window in pixels }
-
- PROCEDURE SetZoomSize;
-
- VAR
- r : Rect;
-
- BEGIN
- r := zoomWind^.portRect;
- r.right := r.right - 15; { don't use right edge }
- sizeX := r.right;
- sizeY := r.bottom;
- END;
-
- { return integer between zero and max (inclusive). assumes max is}
- { non-negative.}
-
- FUNCTION Rand (max : integer) : integer;
-
- VAR
- t : integer;
-
- BEGIN
- t := Random;
- IF (t < 0) THEN
- t := -t;
- Rand := t MOD (max + 1);
- END;
-
- { Interpolate one rectangle smoothly into another. Erase the previous}
- { series as the new one is drawn.}
-
- PROCEDURE zoomRect (r1, r2 : Rect);
-
- VAR
- r1left, r1top : integer;
- l, t : integer;
- j : integer;
- hDiff, vDiff, widDiff, htDiff : integer;
- r, b : integer;
- rWid, rHt : integer;
-
- BEGIN
- r1left := r1.left;
- r1top := r1.top;
- hDiff := r2.left - r1left; {positive if moving to right }
- vDiff := r2.top - r1top; {positive if moving down }
-
- rWid := r1.right - r1left;
- rHt := r1.bottom - r1top;
- widDiff := (r2.right - r2.left) - rWid;
- htDiff := (r2.bottom - r2.top) - rHt;
-
- { order of evaluation is important in the rect coordinate calculations.}
- { since all arithmetic is integer, you can't save time by calculating}
- { j/zoomSteps and using that - it'll usually be zero.}
-
- FOR j := 1 TO zoomSteps DO
- BEGIN
- FrameRect(zRect[j - 1]); { erase a rectangle }
- l := r1left + (hDiff * j) DIV zoomSteps;
- t := r1top + (vDiff * j) DIV zoomSteps;
- r := l + rWid + (widDiff * j) DIV zoomSteps;
- b := t + rHt + (htDiff * j) DIV zoomSteps;
- SetRect(zRect[j - 1], l, t, r, b);
- FrameRect(zRect[j - 1]);
- END;
- END;
-
- PROCEDURE Idle;
-
- VAR
- i : integer;
- pt1, pt2 : Point;
- dstRect : Rect;
-
- BEGIN
- SetPt(pt1, Rand(sizeX), Rand(sizeY)); { generate new rect }
- SetPt(pt2, Rand(sizeX), Rand(sizeY)); { and zoom to it }
- Pt2Rect(pt1, pt2, dstRect);
- SetWindClip(zoomWind); { don't draw in right edge }
- ZoomRect(zSrcRect, dstRect);
- ResetWindClip;
- zSrcRect := dstRect;
- END;
-
- { just pause zoom display while mouse down}
-
- PROCEDURE Mouse (thePt : point;
- t : longint;
- mods : integer);
- BEGIN
- WHILE (StillDown) DO
- ; { wait until mouse button released }
- END;
-
- { Draw the grow box in white on black. This is tricky: if the window}
- { is inactive, the grow box will be drawn black, as it should be. But}
- { if the window is active, the box will STILL be drawn black on white!}
- { So have to check whether the window is active or not. The test for}
- { active has to be done carefully: the window manager stores 255 and 0}
- { for true and false, not real boolean values.}
-
- PROCEDURE ZDrawGrowBox;
- VAR
- r : Rect;
- zoomPeek : WindowPeek;
-
- BEGIN
- PenMode(notPatCopy);
- DrawGrowBox(zoomWind);
- PenMode(patXor);
- zoomPeek := WindowPeek(zoomWind);
- IF (zoomPeek^.hilited) THEN { grow box draw in white }
- BEGIN { no matter what if active }
- r := zoomWind^.portRect; { - invert to fix }
- r.left := r.right - 14;
- r.top := r.bottom - 14;
- InvertRect(r);
- END;
- END;
-
- PROCEDURE Update (resized : Boolean);
-
- VAR
- i : integer;
- BEGIN
- EraseRect(zoomWind^.portRect);
- ZDrawGrowBox;
- SetWindClip(zoomWind);
- FOR i := 0 TO zoomSteps - 1 DO
- FrameRect(zRect[i]);
- ResetWindClip;
- IF resized THEN
- SetZoomSize; { adjust to new window size }
- END;
-
- PROCEDURE Activate (active : Boolean);
-
- BEGIN
- ZDrawGrowBox;
- IF active THEN
- DisableItem(editMenu, 0)
- ELSE
- EnableItem(editMenu, 0);
- DrawMenuBar;
- END;
-
- PROCEDURE Halt;
- BEGIN
- CloseWindow(zoomWind);
- END;
-
- PROCEDURE ZoomWindInit;
-
- VAR
- i : integer;
- BEGIN
- zoomWind := GetNewWindow(zoomWindRes, NIL, WindowPtr(-1));
- SkelWindow(zoomWind, @Mouse, NIL, @Update, @Activate, NIL, @Halt, @Idle, true);
- { ignore key clicks }
- { no close proc }
- { when done with window }
- { draw a new series }
- { run only when frontmost }
-
- SetZoomSize;
- BackPat(black);
- PenMode(patXor);
- SetRect(zSrcRect, 0, 0, 0, 0);
- FOR i := 0 TO zoomSteps - 1 DO { initialize rect array }
- zRect[i] := zSrcRect;
- END;
- END.